import { HttpStatus } from "@nestjs/common";
import { ApiProperty, PickType } from "@nestjs/swagger";
import { instanceToPlain } from "class-transformer";
import { MimeType } from "file-type";
import { MediaEntity, RoleEntity } from "src/entity";
import { WsEvent } from "src/socket/ws.event.enum";

export class MyResponse<T = any> {
    @ApiProperty({ type: "object" })
    data: T | null;

    @ApiProperty({ default: HttpStatus.OK })
    code: number;

    @ApiProperty({ default: "ok" })
    message: string;

    constructor(code: number = HttpStatus.OK, data: T | null = null, message = "ok") {
        this.code = code;
        this.data = data;
        this.message = message;
    }

    toJson() {
        return instanceToPlain(this);
    }
}

export class MyWsErrorResponse extends MyResponse {
    @ApiProperty({ enum: WsEvent })
    eventName: WsEvent;

    constructor(code: number, event: string, message: string) {
        super(code, null, message);
        this.eventName = event as any;
    }
}

export class FileDownloadInfo {
    @ApiProperty({ type: "string", description: "下载 URL" })
    url: string;

    @ApiProperty({ type: "string", description: "文件名" })
    filename: string;

    @ApiProperty({ type: "number", description: "文件大小" })
    filesize: number;

    @ApiProperty({ type: "string", description: "文件类型" })
    mime?: MimeType;

    @ApiProperty({ type: MediaEntity, description: "媒体文件,播放记录信息" })
    media?: MediaEntity;
}

class Stats {
    @ApiProperty({ type: "number", description: "文件大小" })
    size: number;

    @ApiProperty({ type: "string", description: "访问时间" })
    atime: Date;

    @ApiProperty({ type: "string", description: "修改时间" })
    mtime: Date;

    @ApiProperty({ type: "string", description: "创建时间" })
    ctime: Date;

    @ApiProperty({ type: "number", description: "访问时间 毫秒" })
    atimeMs: number;

    @ApiProperty({ type: "number", description: "修改时间 毫秒" })
    mtimeMs: number;

    @ApiProperty({ type: "number", description: "创建时间 毫秒" })
    ctimeMs: number;
}

export class Folder {
    @ApiProperty({ type: "string", description: "名称" })
    name: string;

    @ApiProperty({ type: "string", description: "绝对路径" })
    absPath: string;

    @ApiProperty({ type: Stats, description: "文件信息" })
    stats?: Stats;

    @ApiProperty({ type: () => [Folder], description: "子目录" })
    childs?: Folder[];

    @ApiProperty({ type: "string", description: "获取错误信息" })
    error?: string;

    @ApiProperty({ type: "boolean", description: "是否是文件" })
    isDirectory?: boolean;
}

export class UserInfo implements Omit<RequsetUser, "roles"> {
    @ApiProperty({ type: "number", description: "数据库id" })
    id: number;

    @ApiProperty({ type: "string", description: "用户名" })
    username: string;

    @ApiProperty({ type: [RoleEntity], description: "角色" })
    roles: Omit<RoleEntity, "permissions">[];

    @ApiProperty({ type: [String], description: "权限" })
    permissions: string[];

    @ApiProperty({ type: "string", description: "创建时间" })
    createTime: Date;

    @ApiProperty({ type: "string", description: "创建时间" })
    updateTime: Date;
}

export class PaginationData<T> {
    @ApiProperty({ type: "object", isArray: true, description: "分页列表数据" })
    list: T[];

    @ApiProperty({ type: "number", description: "总大小" })
    count: number;

    @ApiProperty({ type: "number", description: "每页限制数" })
    limit: number;

    @ApiProperty({ type: "number", description: "下一页数值" })
    nextPage: number;

    @ApiProperty({ type: "boolean", description: "是否还有下一页" })
    hasNext: boolean;
}

export class OnlineUserItem extends PickType(UserInfo, ["id"]) {
    @ApiProperty({ type: "boolean", description: "运行下线" })
    kick: boolean;
}
